home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 001-010 / amok07 / muchmore / muchmore.mod < prev    next >
Text File  |  1993-11-04  |  22KB  |  709 lines

  1. (*---------------------------------------------------------------------------
  2.     :Program.    MuchMore.mod
  3.     :Author.     Fridtjof Siebert
  4.     :Address.    Nobileweg 67, D-7-Stgt-40
  5.     :Phone.      Please write a letter.
  6.     :Shortcut.   [fbs]
  7.     :Version.    1.1
  8.     :Date.       24-Sep-88
  9.     :Copyright.  PD
  10.     :Language.   Modula-II
  11.     :Translator. M2Amiga
  12.     :Imports.    WarpText    [Bill Kelly, fbs]
  13.     :Imports.    NTSC        [fbs]
  14.     :UpDate.     none.
  15.     :Contents.   A Soft-Scrolling ASCII-File Printer.
  16.     :Remark.     Usage: MuchMore {FileName(s)}
  17. ---------------------------------------------------------------------------*)
  18.  
  19. MODULE MuchMore;
  20.  
  21.  
  22. (*-----------------------------  IMPORTs:  --------------------------------*)
  23.  
  24.  
  25. (*------  SYSTEM:  ------*)
  26.  
  27. FROM SYSTEM     IMPORT ADR, ADDRESS, SHIFT;
  28.  
  29. FROM Arguments  IMPORT NumArgs, GetArg;
  30.  
  31. FROM Arts       IMPORT TermProcedure, Terminate, CurrentLevel, BreakPoint,
  32.                        Assert;
  33.  
  34. (*------  Libraries:  ------*)
  35.  
  36. FROM Dos        IMPORT Open, Close, oldFile, Read, FileHandlePtr;
  37.  
  38. FROM Exec       IMPORT GetMsg, ReplyMsg, MessagePtr, WaitPort, AllocMem,
  39.                        FreeMem, MemReqSet, MemReqs;
  40.  
  41. FROM Graphics   IMPORT SetAPen, SetDrMd, jam1, jam2, DrawModes, DrawModeSet,
  42.                        Text, Draw, ViewModes, ViewModeSet, FontStyles,
  43.                        FontStyleSet, FontFlags, FontFlagSet, TextAttr,
  44.                        RastPortPtr, Move, BltBitMap, WaitBOVP, WaitTOF,
  45.                        BitMap, InitBitMap, BltClear, OpenFont, CloseFont,
  46.                        TextFontPtr, WaitBlit;
  47.  
  48. FROM InputEvent IMPORT Qualifiers, QualifierSet;
  49.  
  50. FROM Intuition  IMPORT NewScreen, ScreenFlags, ScreenFlagSet, customScreen,
  51.                        OpenScreen, CloseScreen, MakeScreen, RethinkDisplay,
  52.                        ScreenPtr, NewWindow, WindowFlags, WindowFlagSet,
  53.                        IDCMPFlags, IDCMPFlagSet, OpenWindow, CloseWindow,
  54.                        WindowPtr, IntuiMessage, IntuiMessagePtr;
  55.  
  56. (*------  Standard:  ------*)
  57.  
  58. FROM Strings    IMPORT Length, Copy, first, last;
  59.  
  60. (*------  Other:  ------*)
  61.  
  62. FROM NTSC       IMPORT NTSC;
  63.  
  64. FROM WarpText   IMPORT SetUpFont, NewWarp, NewWarpInfo;
  65.  
  66.  
  67. (*------------------------------  TYPES:  ---------------------------------*)
  68.  
  69.  
  70. TYPE
  71.   TextLinePtr = POINTER TO TextLine;
  72.   TextLine = RECORD
  73.                next: TextLinePtr;
  74.                prev: TextLinePtr;
  75.                text: ARRAY[0..81] OF CHAR;
  76.              END;
  77.  
  78.  
  79. (*-----------------------------  Variables:  ------------------------------*)
  80.  
  81.  
  82. VAR
  83.   NuScreen: NewScreen;
  84.   Screen: ScreenPtr;           (* Screen that contains the Text     *)
  85.   RP: RastPortPtr;             (* Screen's RastPort                 *)
  86.   NuWindow: NewWindow;
  87.   Window: WindowPtr;
  88.   MyFont: TextAttr;
  89.   retry: BOOLEAN;              (* used for Retry/Cancel-Requesters  *)
  90.   MyFile: FileHandlePtr;       (* For loading Textfile              *)
  91.   FirstLine: TextLinePtr;      (* Saved Text                        *)
  92.   TopLine: TextLinePtr;        (* Points to topmost Line            *)
  93.   BottomLine: TextLinePtr;     (* Last Line displayed on Screen     *)
  94.   len: INTEGER;                (* Length of Text's name             *)
  95.   Name: ARRAY[0..127] OF CHAR; (* Text's Name                       *)
  96.   Buffer: POINTER TO ARRAY[0..511] OF CHAR; (* Buffer for Reading   *)
  97.   RQPos: LONGINT;              (* Position within ReadBuffer        *)
  98.   RQLen: LONGINT;              (* Number of CHARs in Buffer         *)
  99.   EOF: BOOLEAN;                (* End of File ?                     *)
  100.   CountFiles: INTEGER;         (* Counts TextFiles                  *)
  101.   i: INTEGER;                  (* used in FOR-NEXT-loops            *)
  102.   NumLines: INTEGER;           (* Number of Lines (32 PAL, 25 NTSC) *)
  103.   BitMaps: ARRAY[0..1] OF BitMap; (* BitMaps for DoubleBuffering    *)
  104.   DisplayedMap: [0..1];        (* actually displayed BitMap         *)
  105.   AnzLines: INTEGER;           (* Length of Text in Lines           *)
  106.   Scroll: BOOLEAN;             (* TRUE = Scroll, FALSE = Wait.      *)
  107.   Down: BOOLEAN;               (* Scroll-Direction                  *)
  108.   MyMsgPtr: IntuiMessagePtr;   (* For receiving Messages            *)
  109.   MyMsg: IntuiMessage;         (* contains Message                  *)
  110.   Shift: BOOLEAN;              (* Shifted Keystroke ?               *)
  111.   Alt: BOOLEAN;                (* Altered Keystroke ?               *)
  112.   RefreshDisplayCnt: CARDINAL; (* Lines to output after HELP        *)
  113.   Font: TextFontPtr;           (* Font for WarpText                 *)
  114.   nwinfo: NewWarpInfo;         (* Info for WarpText                 *)
  115.  
  116.  
  117. (*------------------------  Open Display:  --------------------------------*)
  118.  
  119.  
  120. PROCEDURE InitScreen();
  121.  
  122. BEGIN
  123.  
  124. (*------  Open Screen:  ------*)
  125.  
  126.   WITH MyFont DO
  127.     name := ADR("topaz.font");
  128.     ySize := 8;
  129.     style := FontStyleSet{};
  130.     flags := FontFlagSet{};
  131.   END;
  132.   WITH nwinfo DO
  133.     fontData := AllocMem(2048,MemReqSet{memClear});
  134.     IF fontData=NIL THEN Terminate(0) END;
  135.   END;
  136.   Font := OpenFont(ADR(MyFont));
  137.   SetUpFont(ADR(nwinfo),Font);
  138.   WITH NuScreen DO
  139.     leftEdge     := 0;
  140.     topEdge      := 0;
  141.     width        := 640;
  142.     IF NTSC() THEN
  143.       height     := 216;
  144.       NumLines   := 25;
  145.     ELSE
  146.       height     := 272;
  147.       NumLines   := 32;
  148.     END;
  149.     depth        := 1;
  150.     detailPen    := 0;
  151.     blockPen     := 1;
  152.     viewModes    := ViewModeSet{hires};
  153.     font         := ADR(MyFont);
  154.     defaultTitle := NIL;
  155.     gadgets      := NIL;
  156.     customBitMap := ADR(BitMaps[DisplayedMap]);
  157.   END;
  158.   NuScreen.type := customScreen + ScreenFlagSet{screenQuiet,customBitMap};
  159.   DisplayedMap := 0;
  160.   WITH NuScreen DO
  161.     REPEAT
  162.       InitBitMap(BitMaps[DisplayedMap],depth,width,height);
  163.       WITH BitMaps[DisplayedMap] DO
  164.         planes[0] := AllocMem(width DIV 8 * height,MemReqSet{chip,memClear});
  165.         IF planes[0]=NIL THEN Terminate(0) END;
  166.       END;
  167.       DisplayedMap := 1 - DisplayedMap;
  168.     UNTIL DisplayedMap = 0;
  169.   END;
  170.   Screen := OpenScreen(NuScreen);
  171.   Assert(Screen#NIL,ADR("OpenScrn failed !!"));
  172.   RP := ADR(Screen^.rastPort);
  173.   RP^.bitMap := ADR(BitMaps[1-DisplayedMap]);
  174.   DEC(Screen^.height,16);
  175.   INC(Screen^.viewPort.rasInfo^.ryOffset,8);
  176.   MakeScreen(Screen); RethinkDisplay();
  177.  
  178. (*------  Open Window:  ------*)
  179.  
  180.   WITH NuWindow DO
  181.     leftEdge   := 0;
  182.     topEdge    := 10;
  183.     width      := 640;
  184.     height     := Screen^.height-10;
  185.     detailPen  := 0;
  186.     blockPen   := 1;
  187.     idcmpFlags := IDCMPFlagSet{rawKey};
  188.     flags      := WindowFlagSet{borderless,activate};
  189.     firstGadget:= NIL;
  190.     checkMark  := NIL;
  191.     title      := NIL;
  192.     screen     := Screen;
  193.     bitMap     := NIL;
  194.     minWidth   := 0;
  195.     minHeight  := 0;
  196.     maxWidth   := -1;
  197.     maxHeight  := -1;
  198.     type       := customScreen;
  199.   END;
  200.   Window := OpenWindow(NuWindow);
  201.   Assert(Window#NIL,ADR("OpenWindow failed!!!"));
  202.  
  203. END InitScreen;
  204.  
  205.  
  206. (*------  Flip Buffers:  ------*)
  207.  
  208.  
  209. PROCEDURE FlipBitMap();
  210.  
  211. BEGIN
  212.   RP^.bitMap := ADR(BitMaps[DisplayedMap]);
  213.   DisplayedMap := 1 - DisplayedMap;
  214.   Screen^.viewPort.rasInfo^.bitMap := ADR(BitMaps[DisplayedMap]);
  215.   MakeScreen(Screen); RethinkDisplay();
  216. END FlipBitMap;
  217.  
  218.  
  219. (*------  Read one TextLine into a Variable:  ------*)
  220.  
  221.  
  222. PROCEDURE GetTextLine(Line: TextLinePtr): BOOLEAN;
  223. (* returns TRUE if EOF *)
  224.  
  225. VAR
  226.   Pos: CARDINAL;
  227.  
  228. BEGIN
  229.   Pos := 0;
  230.   WITH Line^ DO
  231.     text := "                                                                                ";
  232.     LOOP
  233.       IF RQPos=RQLen THEN
  234.         RQLen := Read(MyFile,Buffer,SIZE(Buffer^));
  235.         RQPos := 0;
  236.       END;
  237.       text[Pos] := Buffer^[RQPos];
  238.       INC(RQPos);
  239.       IF text[Pos]<" " THEN
  240.         CASE ORD(text[Pos]) OF
  241.         09H: REPEAT
  242.                text[Pos] := " ";
  243.                INC(Pos);
  244.              UNTIL (Pos=80) OR (SHIFT(SHIFT(Pos,-3),3)=Pos);
  245.              DEC(Pos); |
  246.         0AH,0DH,0: EXIT; |
  247.         ELSE
  248.           text[Pos] := " ";
  249.         END;
  250.       END;
  251.       INC(Pos);
  252.       IF Pos>=80 THEN EXIT END;
  253.     END;
  254.     IF Pos#80 THEN text[Pos] := " " END;
  255.   END;
  256.   RETURN RQLen=0;
  257. END GetTextLine;
  258.  
  259.  
  260. (*------  Type one Line of Text:  ------*)
  261.  
  262. PROCEDURE TypeLine(Line: TextLinePtr; PosY: INTEGER);
  263.  
  264. BEGIN
  265.   WITH Line^ DO
  266.     WITH nwinfo DO
  267.       bitPlane := RP^.bitMap^.planes[0];
  268.       xLoc := 0; yLoc := PosY;
  269.       WaitBlit();
  270.       NewWarp(ADR(nwinfo),ADR(text),80);
  271.     END;
  272.   END;
  273. END TypeLine;
  274.  
  275.  
  276. (*------  Write Line at Bottom of Text:  ------*)
  277.  
  278.  
  279. PROCEDURE AddBottomLine(Line: TextLinePtr; Fast: BOOLEAN);
  280.  
  281. VAR
  282.   Height: INTEGER;
  283.   i: INTEGER;
  284.  
  285. BEGIN
  286.   WITH Screen^ DO
  287.     TypeLine(Line,NumLines);
  288.     IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,height,ADR(BitMaps[
  289.          DisplayedMap]),0,height+8,640,8,0C0H,1,NIL) = 0 THEN END;
  290.     WITH viewPort.rasInfo^ DO
  291.       IF Fast THEN
  292.         FlipBitMap();
  293.         IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,16,ADR(BitMaps[1-
  294.           DisplayedMap]),0,0,width,height,0C0H,1,NIL) = 0 THEN END;
  295.       ELSE
  296.         DEC(ryOffset,7);
  297.         FlipBitMap();
  298.         Height := height DIV 4;
  299.         FOR i:=0 TO 3 DO
  300.           INC(ryOffset,1);
  301.           MakeScreen(Screen); RethinkDisplay();
  302.           IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,16+i*Height,
  303.                        ADR(BitMaps[1-DisplayedMap]),0,i*Height,
  304.                        width,Height,0C0H,1,NIL) = 0 THEN END;
  305.         END;
  306.         FOR i:=4 TO 6 DO
  307.           INC(ryOffset,1);
  308.           MakeScreen(Screen); RethinkDisplay();
  309.         END;
  310.       END;
  311.     END;
  312.   END;
  313. END AddBottomLine;
  314.  
  315.  
  316. (*------  Write String to Screen:  ------*)
  317.  
  318.  
  319. PROCEDURE Write(String: ARRAY OF CHAR);
  320.  
  321. VAR
  322.   text: TextLine;
  323.  
  324. BEGIN
  325.   text.next := NIL;
  326.   text.prev := NIL;
  327.   text.text := "                                                                                ";
  328.   Copy(text.text,String,0,Length(String));
  329.   text.text[Length(String)] := " ";
  330.   AddBottomLine(ADR(text),FALSE);
  331. END Write;
  332.  
  333.  
  334. (*------  Deallocate Text:  ------*)
  335.  
  336.  
  337. PROCEDURE FreeText(Text: TextLinePtr);
  338. (* This was recursiv, but caused Stack overflow with 4K Stack *)
  339.  
  340. VAR
  341.   text: TextLinePtr;
  342.  
  343. BEGIN
  344.   IF Text#NIL THEN
  345.     WHILE Text^.next#NIL DO Text := Text^.next END;
  346.     WHILE Text^.prev#NIL DO
  347.       text := Text;
  348.       Text := Text^.prev;
  349.       FreeMem(text,SIZE(TextLine));
  350.     END;
  351.     FreeMem(Text,SIZE(TextLine));
  352.   END;
  353. END FreeText;
  354.  
  355.  
  356. (*------  Scroll down one Line:  ------*)
  357.  
  358.  
  359. PROCEDURE ScrollDown(Fast: BOOLEAN; Read: BOOLEAN): BOOLEAN;
  360. (* Returns TRUE if EOF *)
  361.  
  362. VAR
  363.   EOF: BOOLEAN;
  364.   NewDisplay: BOOLEAN;
  365.  
  366. BEGIN
  367.   NewDisplay := TRUE;
  368.   IF (FirstLine=NIL) AND Read THEN
  369.     FirstLine := AllocMem(SIZE(TextLine),MemReqSet{memClear});
  370.     IF FirstLine=NIL THEN Terminate(0) END;
  371.     TopLine := FirstLine; BottomLine := FirstLine;
  372.     EOF := GetTextLine(BottomLine);
  373.     IF EOF THEN
  374.       FreeMem(FirstLine,SIZE(TextLine));
  375.       FirstLine := NIL;
  376.       NewDisplay := FALSE;
  377.     ELSE
  378.       INC(AnzLines);
  379.     END;
  380.   ELSIF (BottomLine^.next=NIL) AND Read THEN
  381.     BottomLine^.next := AllocMem(SIZE(TextLine),MemReqSet{memClear});
  382.     IF BottomLine^.next=NIL THEN Terminate(0) END;
  383.     BottomLine^.next^.prev := BottomLine;
  384.     BottomLine := BottomLine^.next;
  385.     EOF := GetTextLine(BottomLine);
  386.     IF EOF THEN
  387.       BottomLine := BottomLine^.prev;
  388.       FreeMem(BottomLine^.next,SIZE(TextLine));
  389.       BottomLine^.next := NIL;
  390.       NewDisplay := FALSE;
  391.     ELSE
  392.       INC(AnzLines);
  393.     END;
  394.   ELSIF (BottomLine^.next#NIL) AND (BottomLine#NIL) THEN
  395.     BottomLine := BottomLine^.next;
  396.     EOF := FALSE;
  397.   ELSE
  398.     NewDisplay := FALSE;
  399.   END;
  400.   IF NewDisplay THEN
  401.     IF (AnzLines>=NumLines) AND (RefreshDisplayCnt=0) THEN
  402.       TopLine := TopLine^.next;
  403.     END;
  404.     AddBottomLine(BottomLine,Fast);
  405.   END;
  406.   RETURN EOF;
  407. END ScrollDown;
  408.  
  409.  
  410. (*------  Scroll Up one Line:  ------*)
  411.  
  412.  
  413. PROCEDURE ScrollUp(Fast: BOOLEAN);
  414.  
  415. VAR
  416.   Height: INTEGER;
  417.   i: INTEGER;
  418.  
  419. BEGIN
  420.  
  421.   IF (TopLine^.prev#NIL) AND (TopLine^.prev^.prev#NIL) THEN
  422.     TopLine := TopLine^.prev;
  423.     BottomLine := BottomLine^.prev;
  424.     WITH Screen^ DO
  425.       RP^.bitMap := ADR(BitMaps[DisplayedMap]);
  426.       WITH TopLine^ DO
  427.         TypeLine(prev,0);
  428.         IF Fast THEN
  429.           IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0, 0,
  430.                        ADR(BitMaps[1-DisplayedMap]),0,16,
  431.                        width,height-8,0C0H,1,NIL) = 0 THEN END;
  432.         ELSE
  433.           Height := (height-8) DIV 4;
  434.           WITH viewPort.rasInfo^ DO
  435.             IF NOT(Fast) THEN
  436.               FOR i:=1 TO 4 DO
  437.                 DEC(ryOffset,1);
  438.                 MakeScreen(Screen); RethinkDisplay(); (* WaitTOF(); *)
  439.                 IF BltBitMap(ADR(BitMaps[1-DisplayedMap]),0,height-8-i*Height,
  440.                              ADR(BitMaps[1-DisplayedMap]),0,height+8-i*Height,
  441.                              width,Height,0C0H,1,NIL) = 0 THEN END;
  442.               END;
  443.               FOR i:=4 TO 6 DO
  444.                 DEC(ryOffset,1);
  445.                 MakeScreen(Screen); RethinkDisplay(); (* WaitTOF(); *)
  446.               END;
  447.               INC(ryOffset,7);
  448.             END;
  449.           END;
  450.         END;   (* IF FAST THEN ELSE *)
  451.       END;   (* WITH TopLine^ DO *)
  452.       IF BltBitMap(ADR(BitMaps[DisplayedMap]),0,0,
  453.                    ADR(BitMaps[1-DisplayedMap]),0,8,
  454.                    640,8,0C0H,1,NIL) = 0 THEN END;
  455.       FlipBitMap();
  456.     END;   (* WITH Screen^ DO *)
  457.   END;   (* IF TopLine#NIL ... *)
  458. END ScrollUp;
  459.  
  460.  
  461. (*------  Clear Display:  ------*)
  462.  
  463.  
  464. PROCEDURE ClearBitMaps();
  465.  
  466. BEGIN
  467.   WITH BitMaps[0] DO
  468.     BltClear(planes[0],bytesPerRow*rows,0);
  469.   END;
  470.   WITH BitMaps[1] DO
  471.     BltClear(planes[0],bytesPerRow*rows,0);
  472.   END;
  473. END ClearBitMaps;
  474.  
  475.  
  476. (*------  CleanUp:  ------*)
  477.  
  478.  
  479. PROCEDURE CleanUp();
  480.  
  481. BEGIN
  482.   IF Window#NIL THEN CloseWindow(Window) END;
  483.   IF Screen#NIL THEN CloseScreen(Screen) END;
  484.   WITH NuScreen DO
  485.     WITH BitMaps[0] DO
  486.       IF planes[0]#NIL THEN FreeMem(planes[0],width DIV 8 * height) END;
  487.     END;
  488.     WITH BitMaps[1] DO
  489.       IF planes[0]#NIL THEN FreeMem(planes[0],width DIV 8 * height) END;
  490.     END;
  491.   END;
  492.   IF Buffer#NIL THEN FreeMem(Buffer,SIZE(Buffer^)) END;
  493.   IF MyFile#NIL THEN Close(MyFile) END;
  494.   FreeText(FirstLine);
  495.   WITH nwinfo DO
  496.     IF fontData#NIL THEN FreeMem(fontData,2048) END;
  497.   END;
  498. END CleanUp;
  499.  
  500.  
  501. (*------------------------------  MAIN:  ----------------------------------*)
  502.  
  503.  
  504. BEGIN
  505.  
  506. (*------  Init:  ------*)
  507.  
  508.   Screen := NIL; Window := NIL; FirstLine := NIL; Buffer := NIL;
  509.   TopLine := NIL; BottomLine := NIL; MyFile := NIL; AnzLines := 0;
  510.   Scroll := TRUE; Down := TRUE; nwinfo.fontData := NIL;
  511.   TermProcedure(CleanUp);
  512.   InitScreen();
  513.   Buffer := AllocMem(SIZE(Buffer^),MemReqSet{chip,memClear});
  514.   IF Buffer=NIL THEN Terminate(0) END;
  515.  
  516. (*------  Open File(s):  ------*)
  517.  
  518.   IF NumArgs()=0 THEN
  519.  
  520.     Write("                          MuchMore");
  521.     Write("                       =============="); Write("");
  522.     Write("   A Soft-Scrolling ASCII-File-Printer."); Write("");
  523.     Write("   Usage: "); Write("");
  524.     Write("     MuchMore {FileName(s)}"); Write("");
  525.     Write("   To Start from Workbench Shift-click Texts to Print before"); Write("");
  526.     Write("   doubleclicking MuchMore. "); Write("");
  527.     Write("   Texts whose Default Tool is MuchMore just need to be doubleclicked"); Write("");
  528.     Write("   This should work on NTSC as well as on PAL Amigas."); Write("");
  529.     Write("   © 1988 Fridtjof Siebert, Nobileweg 67, D-7000-Stuttgart-40");
  530.     Write("     Thanx to Bill Kelly for his WarpText-routines!"); Write("");
  531.     Write("     This is free to be spread on PD or Shareware Disks, as long as");
  532.     Write("     you leave my name in.");
  533.     Write("     It's illegal to make any profit of this without my permission !");
  534.     IF NOT(NTSC()) THEN
  535.       FOR i:=0 TO 6 DO Write(""); END;
  536.     END;
  537.  
  538.     LOOP
  539.       WaitPort(Window^.userPort);
  540.       MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
  541.       IF MyMsgPtr^.code<128 THEN EXIT END;
  542.       ReplyMsg(MyMsgPtr);
  543.     END;
  544.     ReplyMsg(MyMsgPtr);
  545.  
  546.   ELSE
  547.  
  548.     CountFiles := 1;
  549.     LOOP
  550.  
  551.       WHILE (CountFiles<=NumArgs()) AND (MyFile=NIL) DO
  552.         GetArg(CountFiles,Name,len);
  553.         MyFile := Open(ADR(Name),oldFile);
  554.         RQPos := -1; RQLen := -1;
  555.         INC(CountFiles);
  556.       END;
  557.  
  558. (*------  Type Text:  ------*)
  559.  
  560.       IF Scroll THEN
  561.         IF Down THEN
  562.           IF ScrollDown(FALSE,MyFile#NIL) THEN
  563.             Close(MyFile);
  564.             MyFile := NIL;
  565.           END;
  566.           IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
  567.         ELSE
  568.           ScrollUp(FALSE);
  569.         END;
  570.       ELSE
  571.         WaitPort(Window^.userPort);
  572.       END;
  573.  
  574.       MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
  575.  
  576.       IF MyMsgPtr#NIL THEN
  577.  
  578.         MyMsg := MyMsgPtr^;
  579.         ReplyMsg(MessagePtr(MyMsgPtr));
  580.  
  581.         WITH MyMsg DO
  582.  
  583.           IF class=IDCMPFlagSet{rawKey} THEN
  584.  
  585.             Shift := (lShift   IN QualifierSet(qualifier)) OR
  586.                      (rShift   IN QualifierSet(qualifier)) OR
  587.                      (capsLock IN QualifierSet(qualifier));
  588.  
  589.             Alt   := (lAlt     IN QualifierSet(qualifier)) OR
  590.                      (rAlt     IN QualifierSet(qualifier));
  591.  
  592.             CASE code OF
  593.  
  594.             40H:  IF Down THEN                      (* Space *)
  595.                     Scroll := NOT(Scroll);
  596.                     IF (BottomLine^.next=NIL) AND (MyFile=NIL) THEN
  597.                       EXIT;
  598.                     END;
  599.                   ELSE
  600.                     Down := TRUE;
  601.                     Scroll := TRUE;
  602.                   END; |
  603.  
  604.             41H:  IF RefreshDisplayCnt=0 THEN         (* BackSpace *)
  605.                     IF Down THEN
  606.                      Down := FALSE;
  607.                       Scroll := TRUE;
  608.                     ELSE
  609.                       Scroll := NOT(Scroll);
  610.                     END;
  611.                   END; |
  612.  
  613.             4DH:  i:=1; IF Alt THEN i:=NumLines END;         (* Down *)
  614.                   WHILE i#0 DO
  615.                     IF ScrollDown(NOT(Shift),MyFile#NIL) THEN
  616.                       Close(MyFile);
  617.                       MyFile := NIL;
  618.                     END;
  619.                     IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
  620.                     DEC(i);
  621.                   END;
  622.                   Scroll := FALSE; |
  623.  
  624.             4CH:  i:=1; IF Alt THEN i:=NumLines END;         (* Up *)
  625.                   WHILE i#0 DO
  626.                     IF RefreshDisplayCnt=0 THEN
  627.                       ScrollUp(NOT(Shift));
  628.                       Scroll := FALSE;
  629.                     END;
  630.                     DEC(i);
  631.                   END; |
  632.  
  633.             44H:  IF ScrollDown(FALSE,MyFile#NIL) THEN       (* CR *)
  634.                     Close(MyFile);
  635.                     MyFile := NIL;
  636.                   END;
  637.                   IF RefreshDisplayCnt#0 THEN DEC(RefreshDisplayCnt) END;
  638.                   Scroll := FALSE; |
  639.  
  640.             23H:  TopLine := FirstLine;                      (* F *)
  641.                   BottomLine := FirstLine;
  642.                   ClearBitMaps();
  643.                   RefreshDisplayCnt := NumLines-2;
  644.                   AddBottomLine(BottomLine,FALSE);
  645.                   Scroll := TRUE;
  646.                   Down := TRUE; |
  647.  
  648.             28H:  WHILE BottomLine^.next#NIL DO              (* L *)
  649.                     BottomLine := BottomLine^.next;
  650.                   END;
  651.                   i:=1;
  652.                   WHILE (i<NumLines) AND (BottomLine^.prev#NIL) DO
  653.                     BottomLine := BottomLine^.prev;
  654.                     INC(i);
  655.                   END;
  656.                   RefreshDisplayCnt := NumLines-2;
  657.                   TopLine := BottomLine;
  658.                   ClearBitMaps();
  659.                   AddBottomLine(BottomLine,FALSE);
  660.                   Scroll := TRUE; Down := TRUE; |
  661.  
  662.             5FH,25H: ClearBitMaps();
  663.                   Write("                          MuchMore");
  664.                   Write("                       =============="); Write("");
  665.                   Write("    Available Commands:"); Write("");
  666.                   Write("      Space:           Start / Stop Scrolling. Quit at end of File."); Write("");
  667.                   Write("      BackSpace:       Start / Stop Scrolling backwards."); Write("");
  668.                   Write("      Up/Down:         Scroll quick one Line up or down."); Write("");
  669.                   Write("      Shift & Up/Down: Scroll one Line up or down."); Write("");
  670.                   Write("      Alt & Up/Down:   Scroll one Page up or down."); Write("");
  671.                   Write("      F:               Jump to first Page."); Write("");
  672.                   Write("      L:               Jump to last (loaded) Page."); Write("");
  673.                   Write("      HELP, H:         Show Commands."); Write("");
  674.                   Write("      ESC, Q, X:       Quit."); Write("");
  675.                   Write("   © 1988 Fridtjof Siebert, Nobileweg 67, D-7000-Stuttgart-40");
  676.                   IF NOT(NTSC()) THEN
  677.                     FOR i:=0 TO 6 DO Write(""); END;
  678.                   END;
  679.                   LOOP
  680.                     WaitPort(Window^.userPort);
  681.                     MyMsgPtr := ADDRESS(GetMsg(Window^.userPort));
  682.                     IF MyMsgPtr^.code<128 THEN EXIT END;
  683.                     ReplyMsg(MyMsgPtr);
  684.                   END;
  685.                   ReplyMsg(MyMsgPtr);
  686.                   BottomLine := TopLine;
  687.                   RefreshDisplayCnt := NumLines - 2;
  688.                   ClearBitMaps();
  689.                   AddBottomLine(BottomLine,FALSE);
  690.                   Scroll := TRUE; Down := TRUE; |
  691.  
  692.             10H,45H,32H: EXIT; |                        (* ESC, Q, X *)
  693.  
  694.             ELSE
  695.  
  696.             END;   (* CASE code OF *)
  697.  
  698.           END;   (* IF class=IDCMPFlagSet{rawKey} THEN *)
  699.  
  700.         END;   (* WITH MyMsg DO *)
  701.  
  702.       END;   (* IF MyMsgPtr#NIl THEN *)
  703.  
  704.     END;   (* LOOP *)
  705.  
  706.   END;   (* IF NumArgs()=0 THEN ELSE *)
  707.  
  708. END MuchMore.
  709.